package cn.wolfcode.web.controller;

import cn.wolfcode.common.constants.CommonConstants;
import cn.wolfcode.common.web.CommonCodeMsg;
import cn.wolfcode.common.web.Result;
import cn.wolfcode.common.web.anno.RequireLogin;
import cn.wolfcode.domain.OrderInfo;
import cn.wolfcode.domain.SeckillProductVo;
import cn.wolfcode.mq.MQConstant;
import cn.wolfcode.mq.OrderMessage;
import cn.wolfcode.redis.SeckillRedisKey;
import cn.wolfcode.service.IOrderInfoService;
import cn.wolfcode.service.ISeckillProductService;
import cn.wolfcode.util.DateUtil;
import cn.wolfcode.util.UserUtil;
import cn.wolfcode.web.msg.SeckillCodeMsg;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.aspectj.weaver.ast.Or;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

/**
 * Created by lanxw
 */
@RestController
@RequestMapping("/order")
@Slf4j
public class OrderInfoController {
    @Autowired
    private ISeckillProductService seckillProductService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private IOrderInfoService orderInfoService;

    /**
     * 存在超卖问题，需要解决
     * 500线程 10次
     * qps 244
     * redis优化：
     *  4900起步(没有解决超卖)
     *  418 (解决了超卖)
     *  time
     *  seckillId
     *  request
     * @return
     */
    @RequestMapping("/doSeckill")
    @RequireLogin
    public Result<String> DoSeckill(Integer time, Long seckillId, HttpServletRequest request){
//        1 判断是否处于抢购时间
        SeckillProductVo seckillProductVo=seckillProductService.find(time,seckillId);
        boolean legalTime= DateUtil.isLegalTime(seckillProductVo.getStartDate(),seckillProductVo.getTime());
        if(!legalTime){
            return Result.error(CommonCodeMsg.ILLEGAL_OPERATION);
        }

//        2 一个用户只能抢购一个
//        获取token信息
        String token = request.getHeader(CommonConstants.TOKEN_NAME);
        String phone = UserUtil.getUserPhone(redisTemplate,token);
        String orderSetKey= SeckillRedisKey.SECKILL_ORDER_SET.getRealKey(String.valueOf(seckillId));
        if(redisTemplate.opsForSet().isMember(orderSetKey,phone)){
//            提示重复下单
            return Result.error(SeckillCodeMsg.REPEAT_SECKILL);
        }
        //        通过redis控制访问量,让真正只有十个访问进入service方法,并对redis存储的对应数据进行原子性操作
        String seckillStockCountlKey = SeckillRedisKey.SECKILL_STOCK_COUNT_HASH.getRealKey(String.valueOf(time));
        Long remainCount = redisTemplate.opsForHash().increment(seckillStockCountlKey, String.valueOf(seckillId), -1);
        if (remainCount<0){
            return Result.error(SeckillCodeMsg.SECKILL_STOCK_OVER);
        }
//        3保存库存数量足够
        if (seckillProductVo.getStockCount()<0){
            return Result.error(SeckillCodeMsg.SECKILL_STOCK_OVER);
        }
//        使用mq的异步下单
        OrderMessage message=new OrderMessage(time,seckillId,token,Long.parseLong(phone));
        rocketMQTemplate.syncSend(MQConstant.ORDER_PEDDING_TOPIC,message);
//        OrderInfo  orderInfo=orderInfoService.doSickill(phone,seckillProductVo);
        return Result.success("成功进入秒杀队列，请耐心等待结果");
    }
    @RequestMapping("/find")
    @RequireLogin
    public  Result<OrderInfo> find(String orderNo,HttpServletRequest request){
        OrderInfo orderInfo=orderInfoService.findByOrderNo(orderNo);
        String token = request.getHeader(CommonConstants.TOKEN_NAME);
        String phone = UserUtil.getUserPhone(redisTemplate,token);
        if (!phone.equals(String.valueOf(orderInfo.getUserId()))){
            return Result.error(CommonCodeMsg.ILLEGAL_OPERATION);
        }
        return Result.success(orderInfo);
    }
}
